using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using ProtoModels;
using UnityEngine;

public class GGServerRequestsBackend : BehaviourSingletonInit<GGServerRequestsBackend>
{
	public delegate void OnComplete(ServerRequest request);

	public class UrlBuilder
	{
		private string urlBase;

		private Dictionary<string, string> paramPairs = new Dictionary<string, string>();

		private Dictionary<string, List<string>> paramListPairs = new Dictionary<string, List<string>>();

		private string data = string.Empty;

		public UrlBuilder(string hostName)
		{
			urlBase = hostName;
			addParams(GetTimestampAttributeName(), DateTime.UtcNow.ToString());
		}

		public static string GetTimestampAttributeName()
		{
			return "timestamp";
		}

		public UrlBuilder addPath(string path)
		{
			urlBase += path;
			return this;
		}

		public UrlBuilder addData(string newData)
		{
			data = newData;
			return this;
		}

		public UrlBuilder addParams(string paramName, string paramVal)
		{
			paramPairs.Add(paramName, paramVal);
			return this;
		}

		public UrlBuilder addParams(string paramName, List<string> paramVal)
		{
			paramListPairs.Add(paramName, paramVal);
			return this;
		}

		public string SignAndToString(string publicKey, string privateKey)
		{
			string text = urlBase;
			paramPairs.Add("ap", publicKey);
			foreach (KeyValuePair<string, string> paramPair in paramPairs)
			{
				string text2 = text;
				text = text2 + ((!(text == urlBase)) ? "&" : "?") + paramPair.Key + "=" + Uri.EscapeDataString(paramPair.Value);
			}
			foreach (KeyValuePair<string, List<string>> paramListPair in paramListPairs)
			{
				foreach (string item in paramListPair.Value)
				{
					string text2 = text;
					text = text2 + ((!(text == urlBase)) ? "&" : "?") + paramListPair.Key + "=" + Uri.EscapeDataString(item);
				}
			}
			string text3 = Regex.Replace(text, "http(s)?://[^/]+", string.Empty);
			text3 += data;
			string hashSha = Hash.getHashSha256(text3 + privateKey);
			return text + "&sig=" + Uri.EscapeDataString(hashSha);
		}

		public override string ToString()
		{
			string text = urlBase;
			foreach (KeyValuePair<string, string> paramPair in paramPairs)
			{
				string text2 = text;
				text = text2 + ((!(text == urlBase)) ? "&" : "?") + paramPair.Key + "=" + Uri.EscapeDataString(paramPair.Value);
			}
			foreach (KeyValuePair<string, List<string>> paramListPair in paramListPairs)
			{
				foreach (string item in paramListPair.Value)
				{
					string text2 = text;
					text = text2 + ((!(text == urlBase)) ? "&" : "?") + paramListPair.Key + "=" + Uri.EscapeDataString(item);
				}
			}
			return text;
		}
	}

	public class ServerRequest
	{
		public enum RequestStatus
		{
			Success = 0,
			Error = 1,
			NotSent = 2
		}

		public delegate void OnComplete(ServerRequest request);

		public OnComplete onComplete;

		public int groupId;

		public float timeoutSec = 15f;

		public CacheGetStrategy cacheGetStrategy;

		public CacheStategy cache;

		public TimeSpan cacheTimeToLive = TimeSpan.FromHours(6.0);

		public RequestStatus status = RequestStatus.NotSent;

		protected object responseObj;

		public string errorMessage { get; protected set; }

		public T GetResponse<T>() where T : class
		{
			return responseObj as T;
		}

		public virtual object GetResponse()
		{
			return responseObj;
		}

		protected virtual string GetUrl()
		{
			return string.Empty;
		}

		protected virtual WWW CreateQuery()
		{
			return null;
		}

		protected virtual void ParseQueryResponse(WWW query)
		{
			ParseResponse(query.bytes);
		}

		protected virtual void ParseResponse(byte[] bytes)
		{
			responseObj = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
		}

		public virtual string GetCacheKey(string url)
		{
			return RemoveChangingParams(url);
		}

		private string StripParamFromUrl(string url, string paramName)
		{
			int num = url.IndexOf(paramName);
			if (num == -1)
			{
				return url;
			}
			int num2 = num + paramName.Length;
			int num3 = url.IndexOf("&", num2);
			return (num3 == -1) ? url.Remove(num2) : url.Remove(num2, num3 - num2);
		}

		private string RemoveChangingParams(string url)
		{
			url = StripParamFromUrl(url, UrlBuilder.GetTimestampAttributeName());
			url = StripParamFromUrl(url, "sig");
			return url;
		}

		protected virtual bool TryGetFromMemoryCache(string url)
		{
			byte[] array = Singleton<GGRequestCache>.Instance.Get<byte[]>(GetCacheKey(url));
			if (array != null)
			{
				status = RequestStatus.Success;
				ParseResponse(array);
			}
			return array != null;
		}

		protected virtual bool TryGetFromFileCache(string url)
		{
			byte[] array = SingletonInit<GGRequestFileCache>.Instance.Get<byte[]>(GetCacheKey(url));
			if (array != null)
			{
				status = RequestStatus.Success;
				ParseResponse(array);
			}
			return array != null;
		}

		protected virtual void CacheResults(WWW query)
		{
			Singleton<GGRequestCache>.Instance.Put(GetCacheKey(query.url), query.bytes, cacheTimeToLive);
		}

		protected virtual void CacheToFile(WWW query)
		{
			SingletonInit<GGRequestFileCache>.Instance.Put(GetCacheKey(query.url), query.bytes, cacheTimeToLive);
		}

		public virtual bool TryGetFromCache()
		{
			string url = GetUrl();
			if (cache == CacheStategy.GetFromCache)
			{
				if (TryGetFromMemoryCache(url))
				{
					status = RequestStatus.Success;
					return true;
				}
			}
			else if (cache == CacheStategy.CacheToFile && TryGetFromFileCache(url))
			{
				status = RequestStatus.Success;
				return true;
			}
			return false;
		}

		public virtual IEnumerator RequestCoroutine()
		{
			if (!GGSupportMenu.instance.isNetworkConnected())
			{
				if (!TryGetFromCache())
				{
					status = RequestStatus.Error;
					errorMessage = "Not Connected to internet! Please connect and try again";
				}
			}
			else
			{
				if (cacheGetStrategy != CacheGetStrategy.GetFromCacheOnlyIfRequestFails && TryGetFromCache())
				{
					yield break;
				}
				WWW query = CreateQuery();
				float time = 0f;
				bool timeout = false;
				while (!query.isDone)
				{
					yield return null;
					time += RealTime.deltaTime;
					if (time >= timeoutSec)
					{
						Debug.Log("TIMEOUT1");
						timeout = true;
						query.Dispose();
						break;
					}
				}
				if (!timeout && string.IsNullOrEmpty(query.error) && query.bytes != null)
				{
					status = RequestStatus.Success;
					ParseQueryResponse(query);
					if (cache == CacheStategy.GetFromCache)
					{
						CacheResults(query);
					}
					else if (cache == CacheStategy.CacheToFile)
					{
						CacheToFile(query);
					}
					yield break;
				}
				Debug.Log("Request Failed");
				if (cacheGetStrategy != CacheGetStrategy.GetFromCacheOnlyIfRequestFails || !TryGetFromCache())
				{
					if (!timeout)
					{
						errorMessage = query.text;
						Debug.Log("ERROR: " + errorMessage);
					}
					else
					{
						Debug.Log("TIMEOUT");
					}
					status = RequestStatus.Error;
				}
			}
		}
	}

	public class TextureRequest : ServerRequest
	{
		public string url { get; protected set; }

		public Texture2D response
		{
			get
			{
				return GetResponse<Texture2D>();
			}
			set
			{
				responseObj = value;
			}
		}

		public TextureRequest(string url)
		{
			this.url = url;
		}

		public static TextureRequest DownloadImage(string url, OnComplete onComplete)
		{
			TextureRequest textureRequest = new TextureRequest(url);
			textureRequest.onComplete = onComplete;
			textureRequest.cache = CacheStategy.CacheToFile;
			textureRequest.cacheTimeToLive = GGRequestCache.InfiniteTimeToLive();
			return textureRequest;
		}

		protected override string GetUrl()
		{
			return url;
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}

		protected override void ParseQueryResponse(WWW query)
		{
			responseObj = query.texture;
		}

		protected override bool TryGetFromMemoryCache(string url)
		{
			Texture2D texture2D = SingletonInit<GGImageRequestCache>.Instance.Get(GetCacheKey(url));
			if (texture2D != null)
			{
				status = RequestStatus.Success;
				responseObj = texture2D;
			}
			return texture2D != null;
		}

		protected override bool TryGetFromFileCache(string url)
		{
			return TryGetFromMemoryCache(url);
		}

		protected override void CacheResults(WWW query)
		{
			SingletonInit<GGImageRequestCache>.Instance.Put(GetCacheKey(query.url), responseObj as Texture2D, cacheTimeToLive, false);
		}

		protected override void CacheToFile(WWW query)
		{
			SingletonInit<GGImageRequestCache>.Instance.Put(GetCacheKey(query.url), responseObj as Texture2D, cacheTimeToLive, true);
		}

		protected override void ParseResponse(byte[] bytes)
		{
			try
			{
				Texture2D texture2D = new Texture2D(0, 0);
				texture2D.LoadImage(bytes);
				responseObj = texture2D;
			}
			catch (Exception message)
			{
				Debug.LogError(message);
				responseObj = null;
			}
		}
	}

	public class ProtoRequest<T> : ServerRequest where T : class
	{
		public T response
		{
			get
			{
				return GetResponse<T>();
			}
			set
			{
				responseObj = value;
			}
		}

		protected override WWW CreateQuery()
		{
			return null;
		}

		protected override void ParseResponse(byte[] bytes)
		{
			T model = (T)null;
			if (ProtoIO.LoadFromByteStream<T>(bytes, out model))
			{
				responseObj = model;
				return;
			}
			Debug.Log("failed to load");
			responseObj = null;
		}
	}

	private interface PidSetRequest
	{
		void SetPid(string pid);
	}

	public class ProtoRequestPid<T> : ProtoRequest<T>, PidSetRequest where T : class
	{
		public virtual void SetPid(string pid)
		{
		}
	}

	public class NonceRequest : ServerRequest
	{
		protected override string GetUrl()
		{
			return new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.nonceUrlPath).ToString();
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class LeaderboardsRequest : ProtoRequestPid<Lead>
	{
		private string app;

		private string pid;

		private int comp;

		private int e;

		private int sR;

		private string country;

		private string distAroundPlayer;

		private int topEntries;

		private string leadTotalEntries;

		private int version;

		public LeaderboardsRequest(int sR, string c)
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			comp = -1;
			e = 10;
			this.sR = sR;
			country = c;
			distAroundPlayer = "true";
			topEntries = 5;
			leadTotalEntries = "true";
			version = GGServerConstants.instance.leadVersion;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.leadUrlPath).addParams("app", app).addParams("pid", pid)
				.addParams("sR", sR.ToString())
				.addParams("country", country)
				.addParams("res", "protobuf")
				.addParams("distAroundPlayer", distAroundPlayer)
				.addParams("topEntries", topEntries.ToString())
				.addParams("leadTotalEntries", leadTotalEntries)
				.addParams("lv", version.ToString());
			if (comp >= 0)
			{
				urlBuilder.addParams("comp", comp.ToString());
			}
			if (e >= 0)
			{
				urlBuilder.addParams("e", e.ToString());
			}
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class SegmentedLeaderboardsRequest : ProtoRequestPid<CombinationLeads>
	{
		private string app;

		private string pid;

		private int comp;

		private int e;

		private int sR;

		private string country;

		private string distAroundPlayer;

		private int topEntries;

		private string leadTotalEntries;

		private int version;

		public SegmentedLeaderboardsRequest(int sR, string c)
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			comp = -1;
			e = 10;
			this.sR = sR;
			country = c;
			distAroundPlayer = "true";
			topEntries = 5;
			leadTotalEntries = "true";
			version = GGServerConstants.instance.leadVersion;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.getSegmentedLeaderboards).addParams("app", app).addParams("pid", pid)
				.addParams("sR", sR.ToString())
				.addParams("country", country)
				.addParams("res", "protobuf")
				.addParams("distAroundPlayer", distAroundPlayer)
				.addParams("topEntries", topEntries.ToString())
				.addParams("maxEntriesPerLead", GGServerConstants.instance.maxEntriesPerLead.ToString())
				.addParams("leadTotalEntries", leadTotalEntries)
				.addParams("lv", version.ToString());
			if (comp >= 0)
			{
				urlBuilder.addParams("comp", comp.ToString());
			}
			if (e >= 0)
			{
				urlBuilder.addParams("e", e.ToString());
			}
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class ActiveCompetitionRequest : ProtoRequest<CompetitionMessage>
	{
		private DateTime endTime;

		public TimeSpan timeSpanTillEndOfCompetition
		{
			get
			{
				return endTime - DateTime.Now;
			}
		}

		protected override bool TryGetFromMemoryCache(string url)
		{
			ActiveCompetitionRequest activeCompetitionRequest = Singleton<GGRequestCache>.Instance.Get<ActiveCompetitionRequest>(GetCacheKey(url));
			if (activeCompetitionRequest != null)
			{
				endTime = activeCompetitionRequest.endTime;
				base.response = activeCompetitionRequest.response;
			}
			return activeCompetitionRequest != null;
		}

		protected override void CacheResults(WWW query)
		{
			Singleton<GGRequestCache>.Instance.Put(GetCacheKey(query.url), this, timeSpanTillEndOfCompetition);
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.getActiveCompetitionUrlPath).addParams("app", GGServerConstants.instance.appName);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override void ParseResponse(byte[] bytes)
		{
			base.ParseResponse(bytes);
			endTime = GetDateTimeCompEnd(base.response.compEndTimestamp);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class UpdateRequest : ProtoRequestPid<StatusMessage>
	{
		private string pid;

		private string app;

		private int sR;

		private string n;

		private string c;

		private int s;

		private string imageUrl;

		private int version;

		public string nonce;

		public UpdateRequest(int sR, string n, string c)
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			this.sR = sR;
			this.n = n;
			this.c = c;
			s = 0;
			imageUrl = string.Empty;
			version = GGServerConstants.instance.leadVersion;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		public void SetScore(int s)
		{
			this.s = s;
		}

		public void SetImageUrl(string url)
		{
			imageUrl = url;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.updateUrlPath).addParams("app", app).addParams("pid", pid)
				.addParams("sR", sR.ToString())
				.addParams("c", c)
				.addParams("nonce", nonce)
				.addParams("lv", version.ToString());
			if (n != string.Empty)
			{
				urlBuilder.addParams("n", n);
			}
			if (s >= 0)
			{
				urlBuilder.addParams("s", s.ToString());
			}
			if (imageUrl != string.Empty)
			{
				urlBuilder.addParams("image", imageUrl);
			}
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class IdRequest : ProtoRequest<Pid>
	{
		private string fbId;

		private string gId;

		private string installId;

		private string app;

		public IdRequest()
		{
			installId = GGUID.InstallId();
			fbId = string.Empty;
			gId = string.Empty;
			app = GGServerConstants.instance.appName;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.getIdUrlPath).addParams("installId", installId).addParams("app", app);
			if (fbId != string.Empty)
			{
				urlBuilder.addParams("fbId", fbId);
			}
			if (gId != string.Empty)
			{
				urlBuilder.addParams("gId", gId);
			}
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class GetPrizesRequest : ProtoRequestPid<Lead>
	{
		private string app;

		private string pid;

		private int sR;

		private string country;

		private string distAroundPlayer;

		private int topEntries;

		private string leadTotalEntries;

		private string leadType = "nonsegmented";

		public GetPrizesRequest(int sR, string c)
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			this.sR = sR;
			country = c;
			distAroundPlayer = "true";
			topEntries = 5;
			leadTotalEntries = "true";
			leadType = "nonsegmented";
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.getPrizesUrlPath).addParams("app", app).addParams("pid", pid)
				.addParams("sR", sR.ToString())
				.addParams("country", country)
				.addParams("distAroundPlayer", distAroundPlayer)
				.addParams("topEntries", topEntries.ToString())
				.addParams("leadTotalEntries", leadTotalEntries)
				.addParams("leadType", leadType);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class GetPrizesRequestCombinationLead : ProtoRequestPid<CombinationLeads>
	{
		private string app;

		private string pid;

		private int sR;

		private string country;

		private string distAroundPlayer;

		private int topEntries;

		private string leadTotalEntries;

		private string leadType = "segmented";

		public GetPrizesRequestCombinationLead(int sR, string c)
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			this.sR = sR;
			country = c;
			distAroundPlayer = "true";
			topEntries = 5;
			leadTotalEntries = "true";
			leadType = "segmented";
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.getPrizesUrlPath).addParams("app", app).addParams("pid", pid)
				.addParams("sR", sR.ToString())
				.addParams("country", country)
				.addParams("distAroundPlayer", distAroundPlayer)
				.addParams("topEntries", topEntries.ToString())
				.addParams("leadTotalEntries", leadTotalEntries)
				.addParams("maxEntriesPerLead", GGServerConstants.instance.maxEntriesPerLead.ToString())
				.addParams("leadType", leadType);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class AckPrizesRequest : ProtoRequestPid<StatusMessage>
	{
		private string app;

		private string pid;

		public AckPrizesRequest()
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.ackPrizesUrlPath).addParams("app", app).addParams("pid", pid);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class CloudSyncRequest : ProtoRequestPid<CloudSyncData>
	{
		public string nonce;

		public int snapshotId { get; protected set; }

		public string snapshotGUID { get; protected set; }

		public override void SetPid(string pid)
		{
		}

		public void SetVersionInfo(int snapshotId, string snapshotGUID)
		{
			this.snapshotId = snapshotId;
			this.snapshotGUID = snapshotGUID;
		}

		public virtual CloudSyncData GetRequestData()
		{
			return null;
		}
	}

	public class GetCloudSyncDataRequest : CloudSyncRequest
	{
		private string app;

		private string pid;

		public GetCloudSyncDataRequest()
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			base.snapshotId = -1;
			base.snapshotGUID = string.Empty;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		public override CloudSyncData GetRequestData()
		{
			return null;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.getCloudSyncUrlPath).addParams("app", app).addParams("pid", pid)
				.addParams("nonce", nonce);
			if (ConfigBase.instance.cloudSyncType == ConfigBase.GGFileIOCloudSyncTypes.GGSnapshotCloudSync)
			{
				urlBuilder = urlBuilder.addParams("addSnapshotInfo", "true");
			}
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			string url = GetUrl();
			return new WWW(url);
		}
	}

	public class UpdateCloudSyncDataRequest : CloudSyncRequest
	{
		private string app;

		private string pid;

		private string data;

		public UpdateCloudSyncDataRequest()
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			base.snapshotId = -1;
			base.snapshotGUID = string.Empty;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		public void AddData(CloudSyncData syncData)
		{
			data = ProtoIO.SerializeToByte64(syncData);
		}

		public override CloudSyncData GetRequestData()
		{
			CloudSyncData model = null;
			if (!ProtoIO.LoadFromBase64String<CloudSyncData>(data, out model))
			{
				model = new CloudSyncData();
			}
			return model;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.updateCloudSyncUrlPath).addParams("app", app).addParams("pid", pid)
				.addParams("nonce", nonce)
				.addData(data);
			if (base.snapshotId >= 0)
			{
				urlBuilder = urlBuilder.addParams("snapshotId", base.snapshotId.ToString()).addParams("snapshotGUID", base.snapshotGUID);
			}
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			dictionary["Content-Type"] = "text/plain";
			return new WWW(GetUrl(), Encoding.UTF8.GetBytes(data), dictionary);
		}
	}

	public class FacebookLoginRequest : ProtoRequest<FBLogin>
	{
		private string app;

		private string accessToken;

		private string installId;

		public FacebookLoginRequest()
		{
			app = GGServerConstants.instance.appName;
			accessToken = ((!ConfigBase.instance.canUseFacebook) ? string.Empty : GGFacebook.instance.GetAccessToken());
			installId = GGUID.InstallId();
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.FBLoginUrlPath).addParams("app", app).addParams("installId", installId)
				.addParams("accessToken", accessToken);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class FacebookInviteFriends : ProtoRequestPid<InvitableFriends>
	{
		private string app;

		private string pid;

		private int pagesToFetch;

		public FacebookInviteFriends()
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			pagesToFetch = GGServerConstants.instance.fbInvitePagesToFetch;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
			Debug.Log("myPid: " + pid);
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.FBInvitableFriendsPath).addParams("app", app).addParams("pid", pid)
				.addParams("pages", pagesToFetch.ToString());
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class FacebookPlayingFriends : ProtoRequestPid<InvitableFriends>
	{
		private string app;

		private string pid;

		public FacebookPlayingFriends()
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.FBPlayingFriendsPath).addParams("app", app).addParams("pid", pid);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class GGServerPlayerMessages : ProtoRequestPid<ServerMessages>
	{
		private string app;

		private string pid;

		public GGServerPlayerMessages()
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.PlayerGetMessagesPath).addParams("app", app).addParams("pid", pid);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class GGServerMarkMessagesAsRead : ProtoRequestPid<StatusMessage>
	{
		private string app;

		private string pid;

		private string requestIds;

		public GGServerMarkMessagesAsRead(string requestIds)
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			this.requestIds = requestIds;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.MarkMessageReadPath).addParams("app", app).addParams("pid", pid)
				.addParams("requestIds", requestIds);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class GGServerGetFriendProfiles : ProtoRequestPid<FriendsProfiles>
	{
		private string app;

		private string pid;

		private List<string> files;

		public GGServerGetFriendProfiles(List<string> files)
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
			this.files = files;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.getFriendProfilesPath).addParams("app", app).addParams("pid", pid)
				.addParams("filename", files);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			return new WWW(GetUrl());
		}
	}

	public class GetPlayerPositionsRequest : ProtoRequestPid<PlayerPositions>
	{
		private string app;

		private string pid;

		private string data;

		public GetPlayerPositionsRequest()
		{
			app = GGServerConstants.instance.appName;
			pid = string.Empty;
		}

		public override void SetPid(string pid)
		{
			this.pid = pid;
		}

		public void AddData(PlayerPositions players)
		{
			data = ProtoIO.SerializeToByte64(players);
		}

		public PlayerPositions GetRequestData()
		{
			PlayerPositions model = null;
			if (!ProtoIO.LoadFromBase64String<PlayerPositions>(data, out model))
			{
				model = new PlayerPositions();
			}
			return model;
		}

		protected override string GetUrl()
		{
			UrlBuilder urlBuilder = new UrlBuilder(GGServerConstants.instance.urlBase).addPath(GGServerConstants.instance.getPlayerPositionList).addParams("app", app).addParams("pid", pid)
				.addParams("res", "protobuf")
				.addData(data);
			return urlBuilder.SignAndToString(GGServerConstants.instance.publicKey, GGServerConstants.instance.privateKey);
		}

		protected override WWW CreateQuery()
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			dictionary["Content-Type"] = "text/plain";
			return new WWW(GetUrl(), Encoding.UTF8.GetBytes(data), dictionary);
		}
	}

	protected RequestsBackendStorage storage;

	protected string storageFilename = "backendStorage.bytes";

	private string memoryCachedPlayerId = string.Empty;

	public string cachedPlayerId
	{
		get
		{
			if (!string.IsNullOrEmpty(memoryCachedPlayerId))
			{
				return memoryCachedPlayerId;
			}
			if (!string.IsNullOrEmpty(storage.lastKnownPid))
			{
				return storage.lastKnownPid;
			}
			return string.Empty;
		}
		protected set
		{
			memoryCachedPlayerId = value;
			storage.lastKnownPid = value;
			Save();
		}
	}

	public void Save()
	{
		ProtoIO.SaveToFile(storageFilename, storage);
	}

	public override void Init()
	{
		base.Init();
		if (!ProtoIO.LoadFromFile<RequestsBackendStorage>(storageFilename, out storage))
		{
			storage = new RequestsBackendStorage();
			Save();
		}
	}

	public void GetCompetitionLeaderboards(LeaderboardsRequest lead, OnComplete onComplete)
	{
		Debug.Log("GetLeaderboards");
		StartCoroutine(DoExecuteRequestWithPid(lead, onComplete));
	}

	public void GetSegmentedCompetitionLeaderboards(SegmentedLeaderboardsRequest lead, OnComplete onComplete)
	{
		Debug.Log("GetLeaderboards");
		StartCoroutine(DoExecuteRequestWithPid(lead, onComplete));
	}

	public void UpdateUser(UpdateRequest update, OnComplete onComplete)
	{
		Debug.Log("UpdateUser");
		StartCoroutine(DoUpdateUser(update, onComplete));
	}

	private IEnumerator DoUpdateUser(UpdateRequest update, OnComplete onComplete)
	{
		ServerRequest playerId = null;
		yield return StartCoroutine(GetPlayerId(delegate(ServerRequest pid)
		{
			playerId = pid;
		}));
		NonceRequest nonceReq = new NonceRequest();
		yield return StartCoroutine(nonceReq.RequestCoroutine());
		if (playerId.status == ServerRequest.RequestStatus.Success && nonceReq.status == ServerRequest.RequestStatus.Success)
		{
			update.SetPid(playerId.GetResponse<Pid>().pid);
			update.nonce = nonceReq.GetResponse<string>();
			Debug.Log("Nonce: " + update.nonce);
			yield return StartCoroutine(update.RequestCoroutine());
		}
		Debug.Log("Update success " + update.status);
		if (onComplete != null)
		{
			onComplete(update);
		}
	}

	public IEnumerator GetPlayerId(OnComplete onComplete)
	{
		Debug.Log("GetPlayerId");
		IdRequest idRequest = new IdRequest();
		if (!string.IsNullOrEmpty(memoryCachedPlayerId))
		{
			idRequest.response = new Pid();
			idRequest.response.pid = memoryCachedPlayerId;
			idRequest.status = ServerRequest.RequestStatus.Success;
			onComplete(idRequest);
			yield break;
		}
		yield return StartCoroutine(idRequest.RequestCoroutine());
		if (idRequest.status == ServerRequest.RequestStatus.Success)
		{
			Debug.Log("Player Id receieved " + idRequest.GetResponse<Pid>().pid);
			if (string.IsNullOrEmpty(memoryCachedPlayerId))
			{
				cachedPlayerId = idRequest.GetResponse<Pid>().pid;
			}
		}
		else if (!string.IsNullOrEmpty(storage.lastKnownPid))
		{
			idRequest.response = new Pid();
			idRequest.response.pid = cachedPlayerId;
			idRequest.status = ServerRequest.RequestStatus.Success;
			onComplete(idRequest);
			yield break;
		}
		if (onComplete != null)
		{
			onComplete(idRequest);
		}
	}

	public IEnumerator GetFacebookLogin(OnComplete onComplete)
	{
		Debug.Log("GetFacebookLogin");
		FacebookLoginRequest loginRequest = new FacebookLoginRequest();
		yield return StartCoroutine(loginRequest.RequestCoroutine());
		if (loginRequest.status == ServerRequest.RequestStatus.Success)
		{
			Debug.Log("Caching player id");
			cachedPlayerId = loginRequest.GetResponse<FBLogin>().pid;
		}
		if (onComplete != null)
		{
			onComplete(loginRequest);
		}
	}

	public void GetActiveCompetition(ActiveCompetitionRequest req, OnComplete onComplete)
	{
		StartCoroutine(DoRequest(req, onComplete));
	}

	private IEnumerator DoRequest(ActiveCompetitionRequest req, OnComplete onComplete)
	{
		yield return StartCoroutine(req.RequestCoroutine());
		if (onComplete != null)
		{
			onComplete(req);
		}
	}

	public void GetPrizes(GetPrizesRequest getPrizesRequest, OnComplete onComplete)
	{
		Debug.Log("GetPrizes");
		StartCoroutine(DoExecuteRequestWithPid(getPrizesRequest, onComplete));
	}

	public void GetCombinationPrizes(GetPrizesRequestCombinationLead getPrizesRequest, OnComplete onComplete)
	{
		Debug.Log("GetPrizes");
		StartCoroutine(DoExecuteRequestWithPid(getPrizesRequest, onComplete));
	}

	public void AckPrizes(AckPrizesRequest ackPrizesRequest, OnComplete onComplete)
	{
		Debug.Log("AckPrizes");
		StartCoroutine(DoExecuteRequestWithPid(ackPrizesRequest, onComplete));
	}

	public Coroutine GetCSData(CloudSyncRequest dataRequest, OnComplete onComplete)
	{
		return StartCoroutine(DoSyncCsData(dataRequest, onComplete));
	}

	public void UpdateCSData(UpdateCloudSyncDataRequest dataRequest, OnComplete onComplete)
	{
		Debug.Log("UpdateCSData");
		StartCoroutine(DoSyncCsData(dataRequest, onComplete));
	}

	private IEnumerator DoSyncCsData(CloudSyncRequest dataRequest, OnComplete onComplete)
	{
		ServerRequest playerId = null;
		yield return StartCoroutine(GetPlayerId(delegate(ServerRequest pid)
		{
			playerId = pid;
		}));
		NonceRequest nonceReq = new NonceRequest();
		Debug.Log("nonce cache policy: " + nonceReq.cache);
		yield return StartCoroutine(nonceReq.RequestCoroutine());
		if (playerId.status == ServerRequest.RequestStatus.Success && nonceReq.status == ServerRequest.RequestStatus.Success)
		{
			dataRequest.SetPid(playerId.GetResponse<Pid>().pid);
			dataRequest.nonce = nonceReq.GetResponse<string>();
			Debug.Log("Nonce: " + dataRequest.nonce);
			yield return StartCoroutine(dataRequest.RequestCoroutine());
		}
		if (onComplete != null)
		{
			onComplete(dataRequest);
		}
	}

	public void GetFacebookInvites(FacebookInviteFriends inviteRequest, OnComplete onComplete)
	{
		Debug.Log("inviteRequest");
		inviteRequest.cache = CacheStategy.GetFromCache;
		inviteRequest.cacheTimeToLive = TimeSpan.FromSeconds(30.0);
		StartCoroutine(DoExecuteRequestWithPid(inviteRequest, onComplete));
	}

	public void GetFacebookPlayers(FacebookPlayingFriends playersRequest, OnComplete onComplete)
	{
		Debug.Log("playersRequest");
		playersRequest.cache = CacheStategy.GetFromCache;
		playersRequest.cacheTimeToLive = TimeSpan.FromSeconds(30.0);
		StartCoroutine(DoExecuteRequestWithPid(playersRequest, onComplete));
	}

	public void GetMessagesForPlayer(GGServerPlayerMessages messagesRequest, OnComplete onComplete)
	{
		Debug.Log("messagesRequest");
		messagesRequest.cache = CacheStategy.GetFromCache;
		messagesRequest.cacheTimeToLive = TimeSpan.FromMinutes(10.0);
		StartCoroutine(DoExecuteRequestWithPid(messagesRequest, onComplete));
	}

	public void MarkMessagesAsRead(GGServerMarkMessagesAsRead markAsReadRequest, OnComplete onComplete)
	{
		Debug.Log("markAsReadRequest");
		StartCoroutine(DoExecuteRequestWithPid(markAsReadRequest, onComplete));
	}

	public void GetFriendProfiles(GGServerGetFriendProfiles request, OnComplete onComplete)
	{
		Debug.Log("GetFriendProfiles");
		StartCoroutine(DoExecuteRequestWithPid(request, onComplete));
	}

	public void GetPlayerPositionList(GetPlayerPositionsRequest request, OnComplete onComplete)
	{
		Debug.Log("GetFriendProfiles");
		StartCoroutine(DoExecuteRequestWithPid(request, onComplete));
	}

	private IEnumerator DoExecuteRequestWithPid<T>(ProtoRequestPid<T> request, OnComplete onComplete) where T : class
	{
		ServerRequest playerId = null;
		yield return StartCoroutine(GetPlayerId(delegate(ServerRequest pid)
		{
			playerId = pid;
			if (pid.status == ServerRequest.RequestStatus.Success)
			{
				request.SetPid(pid.GetResponse<Pid>().pid);
			}
		}));
		if (playerId.status == ServerRequest.RequestStatus.Success)
		{
			yield return StartCoroutine(request.RequestCoroutine());
		}
		if (onComplete != null)
		{
			onComplete(request);
		}
	}

	public static DateTime GetDateTimeCompEnd(long seconds)
	{
		return DateTime.Now.AddSeconds(seconds);
	}
}
